#!/bin/bash
## <info> Copy code from host, configure, compile, install dependencies, restart OpenXPKI
test $(whoami) != "root" && echo "Please run this as root: sudo $0" && exit 1
set -o pipefail

#
# Exit handler
#
LOG=$(mktemp)
function _exit () {
    if [ $1 -ne 0 -a $1 -ne 333 ]; then
        echo "================================================================================"
        echo "$0: ERROR - last command exited with code $1, output:"
        echo "================================================================================"
        cat $LOG
    fi
    rm -f $LOG
    exit $1
}

[[ "${@#--help}" != "$@" ]] && cat <<__HELP && exit 1
SYNOPSIS
    $(basename "$0") [OPTIONS]

DESCRIPTION
    $(cat "$0" | grep "[[:blank:]]#*[[:blank:]]*<info>" | cut -d ">" -f2 | sed s/'^[[:blank:]]*'//)

OPTIONS
    --no-restart
        Skip restarting OpenXPKI and Apache.

    --no-i18n
        Skip updating internationalization files.

    --no-compile
        Skip compiling XS code parts.

    --no-dbconf
        Skip database configuration.

    --fast
        Shortcut for "--no-i18n --no-compile --no-dbconfig".

    --full
        Overwrite /etc/openxpki with modified sample config.
        (Re-)create database and import certificates.
__HELP

trap '_exit $?' EXIT
set -e

#
# Command line options
#
IS_I18N=1
IS_RESTART=1
IS_COMPILE=1
IS_DBCONFIG=1
IS_FULLCONFIG=0
# Bash string manipulation: use # to strip text off $@ and see if string still equals original $@
[[ "${@#--no-i18n}" != "$@" ]]    && IS_I18N=0
[[ "${@#--no-restart}" != "$@" ]] && IS_RESTART=0
[[ "${@#--no-compile}" != "$@" ]] && IS_COMPILE=0
[[ "${@#--no-dbconf}" != "$@" ]]  && IS_DBCONFIG=0
[[ "${@#--fast}" != "$@" ]]       && IS_COMPILE=0 && IS_I18N=0 && IS_DBCONFIG=0
[[ "${@#--full}" != "$@" ]]       && IS_FULLCONFIG=1

#
# Grab and install Perl module dependencies from Makefile.PL using PPI
#
# fix problems with newer Net::DNS:
#rm -f /usr/lib/x86_64-linux-gnu/perl5/5.20/Net/DNS.pm
#cpanm --notest Net::DNS                                               >>$LOG 2>&1

echo "Checking and installing Perl module dependencies"
cpanm --notest PPI                                                    >>$LOG 2>&1
/code-repo/tools/scripts/makefile2cpanfile.pl > /cpanfile
cpanm --quiet --notest --installdeps /

#
# Copy current code and realm CA-ONE config
#
echo ""

# fully overwrite existing config
if [[ $IS_FULLCONFIG -eq 1 ]]; then
    echo "Writing complete OpenXPKI config into /etc/openxpki"
    rsync -a --delete $OXI_TEST_SAMPLECONFIG_DIR/* /etc/openxpki/     >>$LOG 2>&1
    chmod 750              /etc/openxpki/config.d
    chown -R root:openxpki /etc/openxpki/config.d

    # set en_US as default language to get correct I18N translations (e.g. in rpc.fcgi)
    sed -ri 's/^(\s*default_language:).*/\1 en_US/' /etc/openxpki/config.d/system/server.yaml

# partial config update
else
    #  realm democa
    echo "Updating demo realm in /etc/openxpki/config.d/realm/democa"
    rsync -a --delete \
      $OXI_TEST_SAMPLECONFIG_DIR/config.d/realm/democa/* \
      /etc/openxpki/config.d/realm/democa/                             >>$LOG 2>&1
    chown -R root:openxpki /etc/openxpki/config.d/realm/democa/        >>$LOG 2>&1
fi

# set /var/tmp instead of /tmp (where only root has write access)
sed -ri 's/(LOCATION:)\s*\/tmp.*/\1 \/var\/tmp/g' /etc/openxpki/config.d/realm/democa/publishing.yaml

if [[ $IS_DBCONFIG -eq 1 ]]; then
    # database setup
    echo "- configuring MariaDB as database"
    cat <<__DB > /etc/openxpki/config.d/system/database.yaml
    main:
        debug: 0
        type: MariaDB
        host: $OXI_TEST_DB_MYSQL_DBHOST
        port: $OXI_TEST_DB_MYSQL_DBPORT
        name: $OXI_TEST_DB_MYSQL_NAME
        user: $OXI_TEST_DB_MYSQL_USER
        passwd: $OXI_TEST_DB_MYSQL_PASSWORD
__DB
fi

#
# Compile OpenXPKI
#
echo -e "\nCompilation and installation"
echo -e "- synchronizing source code from host to $OXI_CORE_DIR"
rsync -a --delete --exclude=.git/ --exclude=node_modules/ /code-repo/core/                 $OXI_CORE_DIR      >>$LOG 2>&1
rsync -a --delete --exclude=.git/ --exclude=node_modules/ /code-repo/core/server/htdocs/*  /var/www/openxpki/ >>$LOG 2>&1
rsync -a --delete --exclude=.git/ /code-repo/core/server/cgi-bin/* /usr/lib/cgi-bin/                          >>$LOG 2>&1
cat $OXI_TEST_SAMPLECONFIG_DIR/contrib/apache2-openxpki-site.conf \
 | perl -pe 's{^(\s*RewriteRule \^\.\*\$ https://)}{#$1}'\
 > /etc/apache2/sites-available/openxpki.conf

test -e /var/www/openxpki/index.html || ln -s default.html /var/www/openxpki/index.html

# Set version so Makefile.PL does not need "vergen" (which we will not copy to $OXI_CORE_DIR)
OXI_VERSION=$(cat /code-repo/.VERSION_MAJOR <(echo .) /code-repo/.VERSION_MINOR <(echo .) /code-repo/.VERSION_RELEASE | tr -d "\n" )
cat <<__VERSION > $OXI_CORE_DIR/server/OpenXPKI/VERSION.pm
package OpenXPKI::VERSION;
our \$VERSION = '$OXI_VERSION';
1;
__VERSION

echo "- purging possible target locations"
while read -d : path; do
    test $path == "." && continue
    echo "    $path/OpenXPKI*"
    rm -rf $path/OpenXPKI*
    rm -rf $path/auto/OpenXPKI*
done <<< $(perl -e 'print "$_:" for @INC')

pushd $OXI_CORE_DIR/server                                            >>$LOG 2>&1
perl Makefile.PL                                                      >>$LOG 2>&1
if [[ $IS_COMPILE -eq 1 ]]; then
    echo "- compiling OpenXPKI $OXI_VERSION"
    make                                                              >>$LOG 2>&1
fi
echo "- installing OpenXPKI"
make install                                                          >>$LOG 2>&1
popd                                                                  >>$LOG 2>&1

echo "- installing CGI::Session::Driver::openxpki"
mkdir -p /usr/share/perl5/CGI/Session/Driver
cp $OXI_CORE_DIR/server/CGI_Session_Driver/openxpki.pm /usr/share/perl5/CGI/Session/Driver/

if [[ $IS_I18N -eq 1 ]]; then
    echo "- compiling and installing I18N files"
    echo "$OXI_VERSION" > $OXI_CORE_DIR/i18n/VERSION
    pushd $OXI_CORE_DIR/i18n                                          >>$LOG 2>&1
    make                                                              >>$LOG 2>&1
    make install                                                      >>$LOG 2>&1
    popd                                                              >>$LOG 2>&1

    echo "- regenerating locales"
    TEMP_MAKEFILE=$(mktemp)
    cat $OXI_CORE_DIR/i18n/Makefile <(echo -e "print-langs:\n\techo \$(LANGS)") > $TEMP_MAKEFILE
    for lang in $(IFS=' '; make -s -f $TEMP_MAKEFILE print-langs); do
        if ! grep -q ^$lang /etc/locale.gen; then
            echo "    adding $lang to /etc/locale.gen"
            echo "$lang.UTF-8 UTF-8" >> /etc/locale.gen
        fi
    done

    locale-gen                                                        >>$LOG 2>&1
fi

# create SSL keys and certificates and import them into OpenXPKI
if [[ $IS_FULLCONFIG -eq 1 ]]; then
    echo ""
    /vagrant/scripts/oxi-initdb
fi

if [[ $IS_RESTART -eq 1 ]]; then
    echo ""

    # oxi-initdb (above) already restarts OpenXPKI
    if [[ $IS_FULLCONFIG -ne 1 ]]; then
        echo "Restarting OpenXPKI"
        openxpkictl restart                                           >>$LOG 2>&1

        if [[ $(openxpkictl status 2>&1) != *"is running"* ]]; then
            echo -e "\nERROR: Could not start OpenXPKI. Please see logs in /var/log/openxpki"
            exit 333
        fi
    fi

    echo "Restarting Apache"
    systemctl restart apache2                                         >>$LOG 2>&1
fi

echo -e "\nDone."
